#ifndef CLIENT_H
#define CLIENT_H

#include <QDateTime>
#include <QObject>
#include <QTcpSocket>
#include "../Common/common.h"

//TCP通信相关功能

class Client : public QObject //继承QObject
{
    Q_OBJECT

public:
    explicit Client(QObject* parent = nullptr);

    void ConnectToServer(QString ip, int port, int room);                        //接收主窗口-棋盘传来的参数，连接服务器
    bool IsBlack();                                                              //返回棋子颜色
    void GetRoomState(QList<ROOM_STATE> &state);                                 //接收主窗口-棋盘传来的参数，房间状态列表

    //向服务器发送各种TCP消息
    bool SendMsg_Logon();                                                        //发送客户端登录TCP消息
    bool SendMsg_Move(int x,int y);                                              //发送执行行动五子棋落子TCP消息
    bool SendMsg_MoveCC(int x1, int y1, int x2, int y2);                           //发送执行行动象棋走棋TCP消息
    bool SendMsg_Success();                                                      //发送通知获胜TCP消息
    bool SendMsg_Say(QString text);                                              //接收主窗口-棋盘传来的参数，发送说话内容TCP消息
    void SendMsg_HeartBeat();                                                    //发送心跳TCP消息

    //处理服务器发来的各种TCP消息
    void OnMsg(MSG_HEADER *pHeader, char *pData, int nDataLen);                  //处理服务器发来的TCP消息
    void OnMsg_Logon(MSG_HEADER* pHeader);                                       //处理登录TCP消息
    void OnMsg_Start(MSG_HEADER* pHeader);                                       //处理开始TCP消息
    void OnMsg_Move(MSG_HEADER* pHeader);                                        //处理执行五子棋行动落子TCP消息
    void OnMsg_MoveCC(MSG_HEADER* pHeader);                                      //处理执行象棋行动落子TCP消息
    void OnMsg_Say(MSG_HEADER* pHeader);                                         //处理说话TCP消息
    void OnMsg_Offline(MSG_HEADER* pHeader);                                     //处理断开连接TCP消息
    void OnMsg_UpdateRoomState(MSG_HEADER* pHeader, char *pData, int nDataLen);  //处理更新房间状态TCP消息

signals:
    void sigOtherUserMove(int x,int y);                   //五子棋其他玩家行动信号
    void sigOtherUserMoveCC(int x1,int y1, int x2, int y2); //象棋其他玩家行动信号
    void sigNewGame();                  //新游戏信号

    void sigOutput(QString text);       //TextEdit输出text信号
    void sigUpdateRoomState();          //更新房间状态信号

protected:
    void timerEvent(QTimerEvent* e);    //重写定时器事件

private slots:
    void slotConnect();                 //connect信号的槽函数
    void slotDisconnect();              //disconnect信号的槽函数
    void slotReadyRead();                  //readyRead信号的槽函数

private:
    bool Send(MSG_HEADER msg);                             //发简单TCP消息，只有消息头即可
    bool Send(MSG_HEADER msg, char *pData, int nDataLen);  //给发复杂TCP消息，含消息头和附加nDataLen字节的数据

    void Output(QString text);                             //用来发送输出信号

private:
    QString mName;                  //玩游戏时名称
    QTcpSocket* mSocket;            //通信套接字
    int mTimerHeart;                //心跳间隔       定时发送一个心跳包，让对方知道自己还活着，以确保连接的有效性
    QDateTime mHeartBeatTime;       //最近一次心跳时间，超过多少秒认为连接中断

    QList<ROOM_STATE> mRoomState;   //房间状态列表

    //客户端联机后的信息
    int mRoom;                      //房间号
    bool mBlack;                    //棋子颜色

    //解决TCP粘包问题，缓存接收的TCP数据，当满足一个消息能完整解析时再取出来解
    QByteArray mData;
};

#endif // CLIENT_H
